package com.example.reagent_management.ui.statistics

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.lib_base.utils.DateTools
import com.example.reagent_management.ui.operatedialog.repository.HistoryRepository
import com.example.reagent_management.ui.statistics.pojo.OperateTimesAndNum
import com.example.reagent_management.ui.statistics.pojo.ReagentNameAndNum
import com.kunminx.architecture.ui.callback.UnPeekLiveData
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import javax.inject.Inject

@HiltViewModel
class StatisticsViewModel @Inject constructor(private val historyRepository: HistoryRepository) :
    ViewModel() {

    private var dayOrHour:Boolean = false

    val monthData = UnPeekLiveData<List<ReagentNameAndNum>>()
    val hourOutStore = UnPeekLiveData<List<OperateTimesAndNum>>()
    val hourInStore = UnPeekLiveData<List<OperateTimesAndNum>>()
    val weekInStore = UnPeekLiveData<List<OperateTimesAndNum>>()
    val weekOutStore = UnPeekLiveData<List<OperateTimesAndNum>>()

    /**
     * 月前五名排行
     */
    fun getReagentNum() {
        //中国时间 开始为00:00:00  结束 23:59:59
        val startMonth = DateTools.getMonthStartTime(System.currentTimeMillis(), "GMT+8:00")
        val endMonth = DateTools.getMonthEndTime(System.currentTimeMillis(), "GMT+8:00")
        viewModelScope.launch {
            historyRepository.getNameAndNum(startMonth, endMonth).collectLatest {
                //只收集较新的流数据
                delay(200)
                monthData.postValue(it)
            }
        }
    }

    /**
     * 近24小时出入库
     */
    fun getHourStore() {
        dayOrHour = false
        viewModelScope.launch{
            //调用await才开始执行 start = CoroutineStart.LAZY
            async {
                getStoreHistory({ historyRepository.getHourInStore() },
                    { hourInStore.postValue(it) })
            }
            async {
                getStoreHistory({ historyRepository.getHourOutStore() },
                    { hourOutStore.postValue(it) })
            }
        }
    }

    /**
     * week
     */
    fun getWeekStore() {
        dayOrHour = true
        viewModelScope.launch {
            async {
                getStoreHistory({ historyRepository.getWeekStore(true) },
                    { weekInStore.postValue(it) })
            }
            async {
                getStoreHistory({ historyRepository.getWeekStore(false) },
                    { weekOutStore.postValue(it) })
            }
        }
    }

    /**
     * 简单封装，简化书写 kotlin方法可传函数
     */
    private suspend fun getStoreHistory(
        dataSource: () -> Flow<List<OperateTimesAndNum>>,
        postValue: (list: List<OperateTimesAndNum>) -> Unit
    ) {
        dataSource().flowOn(Dispatchers.Default)
            .mapLatest {
                delay(100)
                if (dayOrHour){
                    it.forEachIndexed { index, _ ->
                        it[index].operateTime = DateTools.getDayZH(it[index].operateTime.toLong())
                    }
                }else {
                    it.forEachIndexed { index, _ ->
                        it[index].operateTime = DateTools.getHourZH(it[index].operateTime.toLong())
                    }
                }
                return@mapLatest it
            }
            .catch { e ->
                print("caught1: $e")
            }.collect {
                postValue(it)
            }
    }

    companion object {
        const val TAG = "StatisticsViewModel"
    }
}